/**
 *
 */
package neptune.web.client.services;

import java.util.ArrayList;

import neptune.web.client.model.ApplicationGenericInfo;
import neptune.web.client.model.SerializableVmTemplate;
import neptune.web.client.view.ConsoleManager;

import com.google.gwt.user.client.Timer;
import com.google.gwt.user.client.rpc.AsyncCallback;

/**
 * Questa classe contiene le informazioni necessarie al funzionamento
 * dell'applicativo client. Tutte le informazioni contenute riguardano l'utente
 * attualmente riconosciuto dal server.
 *
 * @author Roberto Bifulco [info@robertobifulco.it, robertobifulco.it]
 *
 */
public class ApplicationDataProvider {

        private static ApplicationDataProvider instance = new ApplicationDataProvider();

        public static int UPDATE_INTERVAL = 5000;
        public static int AUTO_UPDATE_INTERVAL = 20000;

        private String[] roles;
        private int usersNumber;
        private int experimentsNumber;

        private boolean isInitialized = false;
        private long lastUpdate;

        private String userRole;
        private String actualUserName;

        private ArrayList<SerializableVmTemplate> vmTemplates = new ArrayList<SerializableVmTemplate>(
                        0);

        /**
         * @return the vmTemplates
         */
        public ArrayList<SerializableVmTemplate> getVmTemplates() {
                return vmTemplates;
        }

        /**
         * @param vmTemplates
         *            the vmTemplates to set
         */
        public void setVmTemplates(ArrayList<SerializableVmTemplate> vmTemplates) {
                this.vmTemplates = vmTemplates;
        }

        private Timer timer = new Timer() {
                @Override
                public void run() {
                        if (updateNeeded())
                                updateData();
                }
        };

        public String[] getUserRoles() {
                updateData();
                return roles;
        }

        public static ApplicationDataProvider getInstance() {
                return instance;
        }

        public void updateData() {

                if (updateNeeded()) {

                        ConsoleManager.addConsoleMessage("Updating application infos...",
                                        false);

                        ApplicationGenericService.Util.getInstance().getApplicationInfo(
                                        new AsyncCallback<ApplicationGenericInfo>() {

                                                public void onSuccess(ApplicationGenericInfo info) {
                                                        roles = info.getDefinedRoles();
                                                        usersNumber = info.getUserNumber();
                                                        experimentsNumber = info.getExperimentsNumber();
                                                        userRole = info.getActualUserRole();
                                                        vmTemplates = info.getVmTemplates();

                                                        if (!isInitialized)
                                                                isInitialized = true;

                                                        lastUpdate = System.currentTimeMillis();

                                                        ConsoleManager.addConsoleMessage(
                                                                        "Application infos updated.", false);
                                                }

                                                public void onFailure(Throwable arg0) {
                                                        timer.cancel();
                                                        ConsoleManager.addConsoleMessage(
                                                                        "Unable to update application infos. Cause: "
                                                                                        + arg0.getMessage(), true);
                                                }

                                        });
                }
        }

        private boolean updateNeeded() {
                if (System.currentTimeMillis() - lastUpdate > UPDATE_INTERVAL)
                        return true;
                return false;
        }

        /**
         * @param roles
         *            the roles to set
         */
        public void setRoles(String[] roles) {
                this.roles = roles;
        }

        /**
         * @return the usersNumber
         */
        public int getUsersNumber() {
                updateData();
                return usersNumber;
        }

        /**
         * @param usersNumber
         *            the usersNumber to set
         */
        public void setUsersNumber(int usersNumber) {
                this.usersNumber = usersNumber;
        }

        /**
         * @return the experimentsNumber
         */
        public int getExperimentsNumber() {
                updateData();
                return experimentsNumber;
        }

        /**
         * @param experimentsNumber
         *            the experimentsNumber to set
         */
        public void setExperimentsNumber(int experimentsNumber) {
                this.experimentsNumber = experimentsNumber;
        }

        /**
         * @return the isInitialized
         */
        public boolean isInitialized() {
                return isInitialized;
        }

        /**
         * @param isInitialized
         *            the isInitialized to set
         */
        public void setInitialized(boolean isInitialized) {
                this.isInitialized = isInitialized;
        }

        /**
         * @return the lastUpdate
         */
        public long getLastUpdate() {
                return lastUpdate;
        }

        /**
         * @param lastUpdate
         *            the lastUpdate to set
         */
        public void setLastUpdate(long lastUpdate) {
                this.lastUpdate = lastUpdate;
        }

        public void setActualUserRole(String userRole) {
                this.userRole = userRole;
        }

        /**
         * @return the userRole
         */
        public String getActualUserRole() {
                return userRole;
        }

        /**
         * @return the timer
         */
        public Timer getTimer() {
                return timer;
        }


        /**
         * @param actualUserName
         *            the actualUserName to set
         */
        public void setActualUserName(String actualUserName) {
                this.actualUserName = actualUserName;
        }

        /**
         * @return the actualUserName
         */
        public String getActualUserName() {
                return actualUserName;
        }

}
